package com.lsk.mobile;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.google.gson.Gson;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Duang;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.lsk.alipay.alipaylife.AlipaySubmit;
import com.lsk.alipay.alipaylife.LimoAlipaySubmit;
import com.lsk.alipay.constants.AlipayServiceEnvConstants;
import com.lsk.alipay.dispatcher.Dispatcher;
import com.lsk.alipay.executor.ActionExecutor;
import com.lsk.alipay.util.LogUtil;
import com.lsk.alipay.util.RequestUtil;
import com.lsk.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class LimoController extends Controller {

    Cache cache= Redis.use();
    static MobileServices mobileServices = new MobileServices();

    AppletService appletService= Duang.duang(new AppletService());

    ApplyService applyService= Duang.duang(new ApplyService());

    String ALIPAY_PUBLIC_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuP6hHLRH4JFO+XKNXKBDiY7/pl9LfXEiHlBs108vV1jyzHvqt5i1I6I6xcH5W3TnQKyZGJmthbs9EnLf1R8rZhD44jQCgm1W/f8GMaDLuEdyr8/5nfQov3LDrY1BZbrMF7DMqbs8S7k6zml/RD30JtwAriBXX/vPa07LLQGKxRgEjmQpPIxHkZy8tEgtaP5MmCJ4wWVLSx2T1dQlRy11v6X9ohRcRL5OTq9gGE7YQK2BeIuy/vhlF51x+OTOLC70ZgaAte6ryVAe8amQN5Mco0aME59oA9rE4lE6X3Aim5y3s/SGbu5+GJXOv62S0oCbsQ/FodxSACgevIcVCOeXQIDAQAB";

    /**
     * getUserId
     * @return
     */
    public void getUserId() {

        String code=getPara("code");

        ReturnData returnData= applyService.getUserId(code);

        renderJson(returnData);
    }
    /**
     * 支付宝生活号验证
     */
    @Clear
    public void dispatcher(){

        try {
            HttpServletRequest request=getRequest();

            HttpServletResponse response=getResponse();
            //支付宝响应消息
            String responseMsg = "";

            //1. 解析请求参数
            Map<String, String> params = RequestUtil.getRequestParams(request);

            //打印本次请求日志，开发者自行决定是否需要
            LogUtil.log("支付宝请求串", params.toString());

            try {
                //2. 验证签名
                verifySign(params);

                //3. 获取业务执行器   根据请求中的 service, msgType, eventType, actionParam 确定执行器
                ActionExecutor executor = Dispatcher.getExecutor(params);

                //4. 执行业务逻辑
                responseMsg = executor.execute();

            }
            catch (AlipayApiException alipayApiException) {
                //开发者可以根据异常自行进行处理
                alipayApiException.printStackTrace();

            }
            catch (Exception exception) {
                //开发者可以根据异常自行进行处理
                exception.printStackTrace();

            } finally {


                /*给支付宝变量赋值*/

                String applySql="SELECT `value` from sys_config where element=";

                String applyAppId= Db.queryStr(applySql+"'limoAppId'");

                String applyPublicKey= ALIPAY_PUBLIC_KEY;


                String applyPrivateKey= Db.queryStr(applySql+"'limoAppPrivateKey'");

                AlipayServiceEnvConstants.APP_ID=applyAppId;

                AlipayServiceEnvConstants.PRIVATE_KEY=applyPrivateKey;

                AlipayServiceEnvConstants.PUBLIC_KEY=applyPublicKey;


                //5. 响应结果加签及返回
                try {
                    //对响应内容加签
                    responseMsg = applyService.encryptAndSign(responseMsg,
                            AlipayServiceEnvConstants.ALIPAY_PUBLIC_KEY,
                            AlipayServiceEnvConstants.PRIVATE_KEY, AlipayServiceEnvConstants.CHARSET,
                            false, true, AlipayServiceEnvConstants.SIGN_TYPE);

                    //http 内容应答
                    renderText(responseMsg);

                    //开发者自行决定是否要记录，视自己需求
                    LogUtil.log("开发者响应串", responseMsg);

                } catch (AlipayApiException alipayApiException) {
                    //开发者可以根据异常自行进行处理
                    alipayApiException.printStackTrace();
                }
            }
        }catch (Exception e){
            Syslog.error(e);
        }
    }

 /**
     * 验签
     *
     * @param ‘
     * @return
     */
    public void verifySign(Map<String, String> params) throws AlipayApiException {

        if (!AlipaySignature.rsaCheckV2(params, ALIPAY_PUBLIC_KEY,
                AlipayServiceEnvConstants.SIGN_CHARSET, AlipayServiceEnvConstants.SIGN_TYPE)) {
            throw new AlipayApiException("verify sign fail.");
        }
    }




    //请求支付宝接口获取auth_code
    public void login() throws AlipayApiException {

        String classId=getPara("classId");

        setCookie("classId",classId,30*30);

        Map<String,String> maps = new HashMap<String ,String>();

        String sql="SELECT `value` from sys_config where element=";

        String domain= Db.queryStr(sql+"'domain'");  //服务器域名地址

        String applyAppId= Db.queryStr(sql+"'limoAppId'");
        //页面回调地址 必须与应用中的设置一样
        String return_url ="http://"+domain +"/limo/authorization?classId="+classId;
        Syslog.info("重定向地址"+return_url);
        //回调地址必须经encode
        return_url = java.net.URLEncoder.encode(return_url);
        //重定向到授权页面
        String redirectUrl="https://openauth.alipay.com/oauth2/publicAppAuthorize.htm"
                +"?app_id=" + applyAppId + "&scope=auth_user&redirect_uri=" + return_url;
        Syslog.info("发起重定向地址为："+redirectUrl);

        redirect(redirectUrl);

    }

    //回调地址获取用户user_id和用户信息

    public void authorization() throws AlipayApiException {

        String classId=getPara("classId");

        ReturnData returnData=new ReturnData();
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<Map,Map> map =new HashMap(); //转化返回的json字符串
        Map requestParams = getRequest().getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == (values.length-1)) ? valueStr + values[i]:valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        String accessToken= LimoAlipaySubmit.buildRequest(params);
        try{
            if(accessToken!=null && accessToken!=""){
                String imf  =  LimoAlipaySubmit.get(accessToken);
                Gson gson=new Gson();
                map=  gson.fromJson(imf, map.getClass());
                System.out.println(imf);
                String userId= map.get("alipay_user_info_share_response").get("user_id").toString();
                //用户昵称
                String nick_name=map.get("alipay_user_info_share_response").get("nick_name")+"";

                Syslog.info("用户支付宝id为："+userId);

                returnData=apiupMemberService(userId,nick_name);

                Map tokenMap = (Map) returnData.getData();
                String token= (String) tokenMap.get("token");

                setCookie("token", token,60*60*24);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        Syslog.info("类型type="+5);
        setCookie("type","5",60*60*24);



            Syslog.info("传递过来的classId为："+classId);
        getRequest().setAttribute("classId",classId);
        forwardAction("/limo/toSellCardPage");
    }


    /**
     * 支付宝会员处理
     */
    public ReturnData apiupMemberService(String useId,String nick_name2){

        final ReturnData returnData=new ReturnData(true);

        final String alipayId=useId;

        String sql="SELECT *from yx_member where alipayId='"+alipayId+"' and source = 2";

        Record memberInfo=Db.findFirst(sql);

        if (memberInfo==null){

            final String userId= UuidUtil.get32UUID();
            final String salt = UuidUtil.get6UUID();  //盐值
            final String encodePassword = MD5.md5("123456" + salt); //password+salt 使用md加密后
            final String nick_name=nick_name2;
            //开启事务
            Db.tx(new IAtom() {
                @Override
                public boolean run() throws SQLException {
                    String userNameRandom = RadomUtil.getName();//生成一个随机名字
                    try {
                        Record sysUser=new Record().set("id", userId).set("userName", nick_name)
                                .set("userCode", "ali"+Tools.getRandomNum()+Tools.getRandomNum()).set("password", encodePassword).set("salt", salt)
                                .set("locked", 0).set("type", 2).set("alipayId",alipayId);

                        Db.save("sys_user", sysUser);

                        Record memberInfo=new Record().set("id", UuidUtil.get32UUID()).set("source",2)
                                .set("alipayId",alipayId)
                                .set("userId", userId).set("type",2).set("name",nick_name);

                        Db.save("yx_member", memberInfo);

                        String token = AES.AESEncode(userId);

                        Map<String, Record> userMap = new HashMap<>();

                        userMap.put("memberInfo", memberInfo);

                        cache.setex(token, 60 * 60 * 24, userMap);

                        Map result=new HashMap();

                        result.put("memberInfo",memberInfo);

                        result.put("token",token);

                        returnData.setResult(true);
                        returnData.setData(result);

                    } catch (Exception e) {

                        Syslog.error(e);
                        return false;//回滚
                    }
                    return true;
                }
            });

        }else {
            String id =memberInfo.getStr("userId");
            Record record=memberInfo;


            String token = AES.AESEncode(id);

            Map<String, Record> userMap = new HashMap<>();

            userMap.put("memberInfo", record);

            cache.setex(token, 60 * 60 * 24, userMap);

            Map result=new HashMap();

            result.put("memberInfo",record);

            result.put("token",token);

            returnData.setResult(true);

            returnData.setData(result);
        }

        return returnData;

    }

    /**
     * 支付宝小程序授权
     */
    public void applyAuthorization(){

        String code=getPara("code");

        String name=getPara("name");

        ReturnData returnData=applyService.getApplyUserId(code,name);

        renderJson(returnData);

    }

    /**
     * 去卖卡页面
     */
    public void toSellCardPage(){

        String classId=getPara("classId");
        Syslog.info("到卖卡页面的classId"+classId);
        String type="5";      //为5柠檬时代

        Record commodityClass=Db.findFirst("select * from commodity_class where id =?",classId);
        setAttr("commodityClass", commodityClass);      //将商品类放入
        List<Record> classList = mobileServices.getAllCommodityClassService("");

        List<Record> commodityList = mobileServices.getCommodityByClassIdService(classId, type);


        setAttr("commodityClassId", classId);

        setAttr("commodityClassName", commodityClass.getStr("name"));

        setAttr("commodityList", commodityList);

        setAttr("type", type);
        /**
         * //@TODO此处先加一个token
         */
       // setCookie("token","2ADF1F19EC591BFF8C5BF7BCEC9E2B93DCAA49D6839B8FB06FF1BAB67AAA4236F86005FE9BDF758AD63BF7A1EA82FBCE",60*60*24);

        setCookie("type","2",60*60*24);

        setAttr("classList", classList);

        renderJsp("sellCardForLimo.jsp");
    }

    /**
     * 去交易记录页面
     */
    public void toTradeRecordPage(){

        String token = getPara("token");

        token=token==null?getCookie("token"):token;

        Map<String, Record> map = cache.get(token);

        Record record = map.get("memberInfo");
        PageUtil pageUtil = mobileServices.getTradeRecordList(10, 0, record, null,"","","","");
        setAttr("data", pageUtil);
        renderJsp("tradeRecord.jsp");
    }
    /**
     * 流加载交易查询的数据接口
     */
    public void getOrderCardFlowList() {

        String token = getCookie("token");

        if (token == null) {
            token = getHeader("token");
        }
        String cardState = getPara("cardState");    //0交易成功 1 交易失败 2 处理中 3 已打款

        Map<String, Record> map = cache.get(token);

        Integer page = getParaToInt("page");
        Integer limit = 4;
        page = (page == null ? 1 : page);
        PageUtil pageUtil = mobileServices.getTradeRecordList(limit, page, map.get("memberInfo"), cardState,"","","","");
        Map<String, Object> res = new HashMap<>();
        res.put("data", pageUtil.getList());
        int pages = (pageUtil.getTotalRows() / 4) + 1;
        res.put("pages", pages);
        renderJson(res);
    }

    /**
     * 交易记录
     */

    //请求支付宝接口获取auth_code
    public void transfer() throws AlipayApiException {

        String redirctUrl=getPara("uri");

        Syslog.info("重定向网址为："+redirctUrl);

        setCookie("transferUri",redirctUrl,60);


        String sql="SELECT `value` from sys_config where element=";

        String domain= Db.queryStr(sql+"'domain'");  //服务器域名地址

        String applyAppId= Db.queryStr(sql+"'limoAppId'");
        //页面回调地址 必须与应用中的设置一样
        String return_url ="http://"+domain +"/limo/toMyAuthorization";
        Syslog.info("重定向地址"+return_url);
        //回调地址必须经encode
        return_url = java.net.URLEncoder.encode(return_url);
        //重定向到授权页面
        String redirectUrl="https://openauth.alipay.com/oauth2/publicAppAuthorize.htm"
                +"?app_id=" + applyAppId + "&scope=auth_user&redirect_uri=" + return_url;
        Syslog.info("发起重定向地址为："+redirectUrl);

        redirect(redirectUrl);

    }

    //回调地址获取用户user_id和用户信息

    public void toMyAuthorization() throws AlipayApiException {

        ReturnData returnData=new ReturnData();
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<Map,Map> map =new HashMap(); //转化返回的json字符串
        Map requestParams = getRequest().getParameterMap();

        String token="";
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == (values.length-1)) ? valueStr + values[i]:valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        String accessToken= LimoAlipaySubmit.buildRequest(params);
        String redirectUrl="";
        try{
            if(accessToken!=null && accessToken!=""){
                String imf  =  LimoAlipaySubmit.get(accessToken);
                Gson gson=new Gson();
                map=  gson.fromJson(imf, map.getClass());
                System.out.println(imf);
                String userId= map.get("alipay_user_info_share_response").get("user_id").toString();
                //用户昵称
                String nick_name=map.get("alipay_user_info_share_response").get("nick_name")+"";

                Syslog.info("用户支付宝id为："+userId);

                returnData=apiupMemberService(userId,nick_name);

                Map tokenMap = (Map) returnData.getData();
                token= (String) tokenMap.get("token");

                setCookie("token", token,60*60*24);


            }
        }catch (Exception e){
            Syslog.error("支付宝回调异常");
            Syslog.error(e);

            String sql="SELECT `value` from sys_config where element=";

            String domain= Db.queryStr(sql+"'domain'");  //服务器域名地址

            String applyAppId= Db.queryStr(sql+"'limoAppId'");
            //页面回调地址 必须与应用中的设置一样

            String return_url ="http://"+domain +"/limo/toMyAuthorization";
            Syslog.info("重定向地址"+return_url);

            //重定向到授权页面
            redirectUrl="https://openauth.alipay.com/oauth2/publicAppAuthorize.htm"
                    +"?app_id=" + applyAppId + "&scope=auth_user&redirect_uri=" + return_url;
            Syslog.info("发起重定向地址为："+redirectUrl);

            redirect(redirectUrl);


        }
        Syslog.info("类型type="+2);

        setCookie("type","2",60*60*24);

        if ("".equals(token)){

            Syslog.error("未获取到token,再次重定向");

            Syslog.info("发起重定向地址为："+redirectUrl);

            redirect(redirectUrl);

        }else {
            redirect("/limo/toTradeRecordPage?token="+token);
        }


    }



}
